Divides physical memory into heap zones and allocates relocatable and non-relocatable blocks within each zone. Passes “handles” to relocatable blocks; updates master pointers when blocks are moved. Can compact memory and purge unused blocks when more memory is needed. Checks for collisions of stack and heap.